package com.tkjt.pms.calc.core;

import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tkjt.pms.common.entity.TkIndexValueActions;
import com.tkjt.pms.modules.common.mapper.TkIndexValueActionsMapper;
import com.tkjt.pms.server.ExecutorCtrl;
import com.tkjt.pms.server.common.ServerParam;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class CalcStatusWatcher {

	@Autowired
	private ExecutorCtrl executorCtrl;

	@Autowired
	private TkIndexValueActionsMapper tkIndexValueActionsMapper;

	/*****************************************************************************************
	 * *@KEY : 考核期
	 * *@value: 计算实例信息
	 * *@目前只支持: 一个后台计算任务
	 * 
	 */
	private Set<String> calcStatus = Collections.synchronizedSet(new HashSet<String>());
	
	public void doWatcher(String dataType, String indexYearMonth, String indexGroup) {
		Set<String> indexGroups = new HashSet<String>();
		indexGroups.add(indexGroup);
		this.doWatcher(dataType, indexYearMonth, indexGroups);
	}

	public void doWatcher(String dataType, String indexYearMonth, Set<String> indexGroups) {
		String statusMessage = dataType + "@" + indexYearMonth;
		calcStatus.add(statusMessage);
		try {
			this.doWatcherProcessor(dataType, indexYearMonth, indexGroups);
		} catch (Exception e) {
			calcStatus.clear();
			log.error(e.getMessage(), e);
		}
	}
	
	public synchronized boolean haveCalcOngoing(String dataType, String indexYearMonth, String indexGroup) {
		Set<String> indexGroups = new HashSet<String>();
		indexGroups.add(indexGroup);
		return this.haveCalcOngoing(dataType, indexYearMonth, indexGroups);
	}

	public synchronized boolean haveCalcOngoing(String dataType, String indexYearMonth, Set<String> indexGroups) {
		if (calcStatus.isEmpty() && executorCtrl.isFinishExecutor(ServerParam.SERVER_TYPE_SINGLE)) {
			return false;
		} else {
			return true;
		}
	}

	public void doWatcherProcessor(String dataType, String indexYearMonth, Set<String> indexGroups) {

		Set<String> ids = this.updateCalcStatusStart(dataType, indexYearMonth, indexGroups);

		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				int maxTimes = 0;
				while (true) {
					try {
						maxTimes++;
						Thread.sleep(30 * 1000);
					} catch (Exception e) {
						e.printStackTrace();
					}
					boolean isFinished = executorCtrl.isFinishExecutor(ServerParam.SERVER_TYPE_SINGLE);
					log.info("calc executor info, finished={}", isFinished);
					if (isFinished) {
						updateCalcStatusSuccessful(ids);
						calcStatus.clear();
						break;
					}
					if (maxTimes >= 120) {
						// 超时机制：超过60分钟没计算完，则不存检查
						// 清除计算线程池
						executorCtrl.shutdownAllTasks(ServerParam.SERVER_TYPE_SINGLE);
						updateCalcStatusError(ids);
						calcStatus.clear();
						break;
					}
				}
			}

		});

		thread.start();

	}

	private Set<String> updateCalcStatusStart(String dataType, String indexYearMonth, Set<String> indexGroups) {

		Set<String> ids = new HashSet<String>();
		for (String indexGroup : indexGroups) {
			TkIndexValueActions entity = new TkIndexValueActions();
			entity.setActionType("calc");
			entity.setDataType(dataType);
			entity.setIndexGroup(indexGroup);
			entity.setIndexYearMonth(indexYearMonth);
			entity.setActionStatus("2");
			entity.setStartTime(new Date());
			tkIndexValueActionsMapper.insert(entity);
			ids.add(entity.getId());
		}

		return ids;
	}

	private void updateCalcStatusSuccessful(Set<String> ids) {
		try {
			for (String id : ids) {
				TkIndexValueActions entity = tkIndexValueActionsMapper.selectById(id);
				entity.setActionStatus("3");
				entity.setEndTime(new Date());
				tkIndexValueActionsMapper.updateById(entity);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}

	private void updateCalcStatusError(Set<String> ids) {
		try {
			for (String id : ids) {
				TkIndexValueActions entity = tkIndexValueActionsMapper.selectById(id);
				entity.setActionStatus("4");
				entity.setEndTime(new Date());
				tkIndexValueActionsMapper.updateById(entity);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}

	/*********************************************************************************
	 * *暂不使用： 目前只支持一个计算任务
	 * 
	 * @param dataType
	 * @param indexYearMonth
	 * @return
	 */
	public synchronized String getCalcStatus(String dataType, String indexYearMonth) {
		String statusKey = dataType + "@" + indexYearMonth;
		if (calcStatus.contains(statusKey)) {
			String statusMsg = "";
			if ("kpi".equals(dataType)) {
				statusMsg += "考核数据,考核期【" + indexYearMonth + "]";
			} else if ("budget".equals(dataType)) {
				statusMsg += "预算数据,考核期【" + indexYearMonth + "]";
			} else {
				statusMsg += "考核期【" + indexYearMonth + "]";
			}
			return statusMsg;
		}
		return null;
	}

}
